#include "EventWrapper.h"
#include "EventException.h"
#include "KeyEvent.h"
#include "TextInputEvent.h"
#include "QuitEvent.h"
#include <sstream>
#include <cstdlib>

EventWrapper::EventWrapper()
{
}

EventWrapper::~EventWrapper()
{
}

void EventWrapper::push(void* header, void* data)
{
    SDL_Event event;
    event.type = SDL_USEREVENT;
    event.user.code = NETWORK;
    event.user.data1 = header;
    event.user.data2 = data;
    SDL_PushEvent(&event);
}

void EventWrapper::push(Event* internalEvent)
{
    SDL_Event event;
    event.type = SDL_USEREVENT;
    event.user.code = INTERNAL;
    event.user.data1 = internalEvent;
    SDL_PushEvent(&event);
}

void EventWrapper::pushQuit()
{
    SDL_Event event;
    event.type = SDL_QUIT;
    SDL_PushEvent(&event);
}

Events EventWrapper::getEvents()
{
    Events result;
    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
        result.push_back(getNextEvent(event));
    }
    return result;
}

Event* EventWrapper::createUserEvent(const SDL_Event& event)
{
    return (Event*)event.user.data1;
}

void EventWrapper::clear(const SDL_Event& event)
{
    free(event.user.data1);
    free(event.user.data2);
}

Event* EventWrapper::getNextEvent(const SDL_Event& event)
{
    switch (event.type)
    {
    case SDL_TEXTINPUT:
        return new TextInputEvent(event.text.text[0]);

    case SDL_KEYDOWN:
        return new KeyEvent(event.key.keysym.sym);

    case SDL_USEREVENT:
    {
        return createUserEvent(event);
    }
    case SDL_QUIT:
        return new QuitEvent();

    default:
        return new Event();
    }
}

Event* EventWrapper::throwEventError(int code)
{
    std::ostringstream errorString;
    errorString << "Event with ENUM code " << code << " not handled";
    throw EventException(errorString.str());
    return new Event();
}

